#include "Poller.h"
#include "Epoller.h"
#include "Ppoller.h"
#include "Eventloop.h"
#include "log/Logger.h"
#include "wrap/epoll.h"
#include "wrap/poll.h"


std::unique_ptr<Poller> Poller::DEFAULT(Eventloop &loop) {
    static const bool isEpoll =  Wrap::epoll_in() == Wrap::poll_in() &&
                                 Wrap::epoll_pri() == Wrap::poll_pri() &&
                                 Wrap::epoll_out() == Wrap::poll_out() &&
                                 Wrap::epoll_err() == Wrap::poll_err() &&
                                 Wrap::epoll_hup() == Wrap::poll_hup() &&
                                 Wrap::poll_rdhup() == Wrap::poll_rdhup();
    if (isEpoll) {
        return std::make_unique<Epoller>(loop);
    }
    return std::make_unique<Ppoller>(loop); 
}

Poller::~Poller() = default;

Utility::timepoint 
Poller::_polling_nfds(int nfds, IOchannelProxyRefs &activeChannels) const {
    _loop.ASSERT_IN_THIS_THREAD();
    const auto errnoSave = errno;
    const auto now = Utility::now();
    if (nfds > 0) {
        _fill_active_channels(nfds, activeChannels);
    }
    else if (nfds == 0) {
        LOG_VERBOSE << "no events happend";
    }
    else if (errnoSave != EINTR) {
        errno = errnoSave;
        LOG_SYSERROR  << "nfds<0 && errno !=    EINTR";
    }
    return now;
}
